package com.biometric.core.authenticator.impl

import androidx.annotation.Keep
import androidx.biometric.BiometricPrompt
import androidx.fragment.app.FragmentActivity
import com.biometric.core.authenticator.BiometricAuthenticator
import com.biometric.core.support.FaceSupportManager
import com.wei.android.lib.fingerprintidentify.Authenticator

/**
 * 人脸识别验证器。必须先判断当前满足人脸识别的条件才能使用该验证器。
 * 验证器内部也会判断当前是否满足进行人脸识别的条件
 */
@Keep
class FaceAuthenticator private constructor(
    val host: FragmentActivity,
    title: String,
    negativeButtonText: String
) : BiometricAuthenticator {

    companion object {
        fun get(activity: FragmentActivity,title: String,negativeButtonText: String): FaceAuthenticator {
            return FaceAuthenticator(activity, title,negativeButtonText)
        }
    }

    private val promptInfo =
        BiometricPrompt.PromptInfo.Builder().setTitle(title)
            .setNegativeButtonText(negativeButtonText)
            .build()
    private lateinit var authenticateListenerWrapper: AuthenticateListenerWrapper
    private lateinit var prompt: BiometricPrompt


    override fun authenticate(authenticateListener: Authenticator.AuthenticateListener) {
        if (FaceSupportManager.isDeviceSupportFaceAuthentication()
                .not()
        ) return authenticateListener.onError(BiometricPrompt.ERROR_HW_UNAVAILABLE, "")
        if (::prompt.isInitialized.not()) {
            authenticateListenerWrapper = AuthenticateListenerWrapper(authenticateListener)
            prompt = BiometricPrompt(host, authenticateListenerWrapper)
        }
        authenticateInternal()
    }

    private fun authenticateInternal() {
        prompt.authenticate(promptInfo)
    }

    override fun reAuthenticate() {
        authenticateInternal()
    }

    override fun cancelAuthenticate() {
        prompt.cancelAuthentication()
    }


    internal class AuthenticateListenerWrapper(private val listener: Authenticator.AuthenticateListener) :
        BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
            listener.onError(errorCode, errString)
        }

        override fun onAuthenticationFailed() {
            listener.onFailed()
        }

        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            listener.onSuccess()
        }
    }
}